const {
  override,
  fixBabelImports,
  addLessLoader,
  addWebpackAlias,
  adjustStyleLoaders,
  addWebpackPlugin,
  disableChunk,
  adjustWorkbox,
  addDecoratorsLegacy,
  addBundleVisualizer,
  disableEsLint,
  addWebpackModuleRule,
  addWebpackExternals
} = require('customize-cra')
const path = require('path')
const paths = require('react-scripts/config/paths')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const WebpackBuildNotifierPlugin = require('webpack-build-notifier')
const WebpackBar = require('webpackbar')
paths.appBuild = path.join(path.dirname(paths.appBuild), 'dist')

// SKIP_PREFLIGHT_CHECK = true

/**
 * 生产环境是否打包 Source Map
 *
 */
const rewiredMap = () => config => {
  config.devtool = config.mode === 'development' ? 'cheap-module-source-map' : false

  return config
}

// path
const resolveAlias = dir => path.join(__dirname, '.', dir)
// build--->prod --->文件设置
const appBuildPathFile = () => config => {
  if (config.mode === 'development') {
    console.log('evn is development, skip build path change...')
  } else if (config.mode === 'production') {
    console.log('evn is production, change build path...')
    //  // 配置打包后的文件位置修改path目录
    config.output.path = __dirname + '/dist'
    config.output.publicPath = '/'
    // 关闭sourceMap
    config.devtool = false
    // 对超过10kb的文件gzip压缩
    config.plugins.push(
      new CompressionWebpackPlugin({
        filename: '[path].gz[query]',
        algorithm: 'gzip',
        test: new RegExp('\\.(js|css)[csdnCommentCode]#39;'),
        threshold: 10240,
        minRatio: 0.8
      })
    )
  }
  config.plugins.push(
    // 进度条
    new WebpackBar()
  )
  return config
}

//生产环境去除console.* functions
const dropConsole = () => {
  return config => {
    config.optimization.minimizer[0].options.minimizer.options.compress = Object.assign(
      config.optimization.minimizer[0].options.minimizer.options.compress,
      {
        drop_console: true
      }
    )
    return config
  }
}
const delConflictingOrder = () => {
  return config => {
    for (let i = 0; i < config.plugins.length; i++) {
      const p = config.plugins[i]
      if (!!p.constructor && p.constructor.name === MiniCssExtractPlugin.name) {
        const miniCssExtractOptions = { ...p.options, ignoreOrder: true }
        config.plugins[i] = new MiniCssExtractPlugin(miniCssExtractOptions)
        break
      }
    }
  }
}
const proxyApi = {
  '/api': {
    target: process.env.REACT_APP_URL, // prod
    changeOrigin: true,
    secure: false,
    xfwd: false,
    pathRewrite: {
      '^/api': '/'
    }
  },
  '/store': {
    // target: '', // staging
    changeOrigin: true,
    secure: false,
    xfwd: false,
    pathRewrite: {
      '^/store': '/'
    }
  }
}

module.exports = {
  webpack: override(
    // antd样式按需加载
    fixBabelImports('import', {
      libraryName: 'antd',
      libraryDirectory: 'es',
      style: true
    }),
    // 处理less
    addLessLoader({
      lessOptions: {
        javascriptEnabled: true,
        localIdentName: '[local]--[hash:base64:5]', // 模块化
        modifyVars: {
          hack: `true; @import (reference) "${path.resolve('src/assets/styles/less/global.less')}";`
        }
      }
    }),
    // 加这个配置解决postcss报错
    adjustStyleLoaders(({ use: [, , postcss] }) => {
      const postcssOptions = postcss.options
      postcss.options = { postcssOptions }
    }),
    addWebpackExternals({
      React: 'React'
    }),
    // 配置svg
    addWebpackModuleRule({
      test: /\.svg$/,
      include: [path.resolve(__dirname, './src/assets/icons/svg')],
      use: [
        {
          loader: 'svg-sprite-loader',
          options: { symbolId: 'icon-[name]' }
        }
      ]
    }),
    // 重命名路径
    addWebpackAlias({
      '@': resolveAlias('src'),
      lib: resolveAlias('src/lib'),
      components: resolveAlias('src/components'),
      images: resolveAlias('src/assets/images'),
      styles: resolveAlias('src/assets/styles'),
      pages: resolveAlias('src/pages'),
      store: resolveAlias('src/store'),
      router: resolveAlias('src/router'),
      locale: resolveAlias('src/locale')
      // 处理警告  React-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work.
    }),

    disableEsLint(), // 忽略eslint警告
    appBuildPathFile(),
    disableChunk(),
    dropConsole(),
    // 关闭mapSource
    rewiredMap(),
    // 打包编译完成提醒
    addWebpackPlugin(
      new WebpackBuildNotifierPlugin({
        title: '',
        suppressSuccess: true
      }),
      new MiniCssExtractPlugin({
        filename: 'static/css/[name].[contenthash].css',
        chunkFilename: 'static/css/[id].[contenthash].css',
        ignoreOrder: false
        // moduleFilename: ({ name }) => `${name.replace('/js/', '/css/')}.css`
      }),

      delConflictingOrder()
    ),
    // 是否打包后打开打包文件分析
    process.env.BUNDLE_VISUALIZE === 'true' && addBundleVisualizer(),
    adjustWorkbox(wb =>
      Object.assign(wb, {
        skipWaiting: true,
        exclude: (wb.exclude || []).concat('index.html')
      })
    ),
    addDecoratorsLegacy() // 装饰器,
  ),
  // 配置devServer
  // devServer: overrideDevServer(
  //   // dev server plugin
  //   watchAll(),
  // ),
  // 配置devServer
  devServer: configFunction => (proxy, allowedHost) => {
    proxy = process.env.NODE_ENV === 'development' ? proxyApi : null
    // allowedHost： 添加额外的地址
    const config = configFunction(proxy, allowedHost)
    return config
  }
}
